package net.sf.calibur.monitor;

import java.util.HashSet;
import java.util.Set;

import org.slf4j.LoggerFactory;

import net.contentobjects.jnotify.JNotify;
import net.contentobjects.jnotify.JNotifyListener;
import net.sf.calibur.engine.CaliburEngine;

public class FileSystemMonitor {
	private JNotifyListener listener;
	private Set<Integer> watchSet;
	private CaliburEngine engine;

	public FileSystemMonitor(CaliburEngine caliburEngine) {
		this.engine = caliburEngine;
		watchSet = new HashSet<Integer>();

		listener = new JNotifyListener() {
			@Override
			public void fileRenamed(int wd, String rootPath, String oldName,
					String newName) {
				engine.addEvent(new FileRenamedEvent(rootPath, oldName, newName));
			}

			@Override
			public void fileModified(int wd, String rootPath, String name) {
				engine.addEvent(new FileModifiedEvent(rootPath, name));
			}

			@Override
			public void fileDeleted(int wd, String rootPath, String name) {
				engine.addEvent(new FileDeletedEvent(rootPath, name));
			}

			@Override
			public void fileCreated(int wd, String rootPath, String name) {
				engine.addEvent(new FileCreatedEvent(rootPath, name));
			}
		};
	}

	public void watchDirectory(String path) throws Exception {
		// watch mask, specify events you care about,
		// or JNotify.FILE_ANY for all events.
		int mask = JNotify.FILE_CREATED | JNotify.FILE_DELETED
				| JNotify.FILE_MODIFIED | JNotify.FILE_RENAMED;

		// watch subtree?
		boolean watchSubtree = true;

		// add actual watch
		int watchId = JNotify.addWatch(path, mask, watchSubtree, listener);
		watchSet.add(watchId);
	}

	public void shutdown() {
		for (int watchId : watchSet) {
			try {
				JNotify.removeWatch(watchId);
			} catch (Exception e) {
				LoggerFactory.getLogger(getClass()).warn(
						"Remove file system watch exception.", e);
			}
		}
	}
}